package com.socket.nio.util;

import java.nio.ByteBuffer;
import java.util.Locale;

/**
 * @author Hexudong
 * @date 2025/4/5
 */
public class ByteBufferPrinter {

    @Deprecated
    public static String printByteBuffer(ByteBuffer buffer) {
        if (buffer == null) {
            return "ByteBuffer is null";
        }
        // 保存原始状态以便恢复
        int originalPosition = buffer.position();
        int originalLimit = buffer.limit();

        // 提取字节数据
        byte[] bytes = new byte[buffer.remaining()];
        buffer.get(bytes);

        // 恢复缓冲区的原始状态
        buffer.position(originalPosition);
        buffer.limit(originalLimit);

        StringBuilder output = new StringBuilder();
        int length = bytes.length;

        for (int offset = 0; offset < length; offset += 16) {
            int lineLength = Math.min(16, length - offset);

            // 1. 偏移量部分
            output.append(String.format(Locale.US, "%08X: ", offset));

            // 2. 十六进制部分
            StringBuilder hexLine = new StringBuilder();
            for (int i = 0; i < 16; i++) {
                if (i < lineLength) {
                    hexLine.append(String.format("%02X ", bytes[offset + i] & 0xFF));
                } else {
                    hexLine.append("   "); // 填充空格保持对齐
                }

                // 在第八字节后添加额外空格
                if (i == 7) {
                    hexLine.append(" ");
                }
            }

            // 修剪末尾多余空格并格式化到固定宽度
            String hexString = hexLine.toString().trim();
            output.append(String.format("%-49s", hexString));

            // 3. ASCII 部分
            StringBuilder asciiLine = new StringBuilder();
            for (int i = 0; i < lineLength; i++) {
                int value = bytes[offset + i] & 0xFF;
                asciiLine.append((value >= 32 && value <= 126) ? (char) value : '.');
            }

            output.append("  ").append(asciiLine).append("\n");
        }
        System.out.println(output);
        return output.toString();
    }

    /**
     * 以 Netty风格的格式打印 ByteBuffer 内容
     * @param buffer 要打印的 ByteBuffer
     */
    public static void prettyPrint(ByteBuffer buffer) {
        if (buffer == null) {
            System.out.println("ByteBuffer is null");
            return;
        }

        // 保存原始位置
        int position = buffer.position();
        int limit = buffer.limit();

        try {
            System.out.println("ByteBuffer info:");
            System.out.println("  Remaining bytes: " + buffer.remaining());
            System.out.println("  Position: " + position);
            System.out.println("  Limit: " + limit);
            System.out.println("  Capacity: " + buffer.capacity());
            System.out.println("  Hex dump:");

            // 重置位置从0开始，打印全部内容
            buffer.position(0);
            buffer.limit(buffer.capacity());

            System.out.println(prettyHexDump(buffer));
        } finally {
            // 恢复原始位置
            buffer.position(position);
            buffer.limit(limit);
        }
    }

    /**
     * 生成 Netty 风格的十六进制转储字符串
     * @param buffer ByteBuffer
     * @return 格式化后的十六进制转储字符串
     */
    private static String prettyHexDump(ByteBuffer buffer) {

        final int bytesPerLine = 16;
        final int length = buffer.remaining();
        final StringBuilder dump = new StringBuilder();
        final StringBuilder hexDump = new StringBuilder();
        final StringBuilder asciiDump = new StringBuilder();

        // 表头
        dump.append("         +-------------------------------------------------+\n");
        dump.append("         |  0  1  2  3  4  5  6  7  8  9  a  b  c  d  e  f |\n");
        dump.append("+--------+-------------------------------------------------+----------------+\n");

        for (int i = 0; i < length; i += bytesPerLine) {
            hexDump.setLength(0);
            asciiDump.setLength(0);

            int lineLength = Math.min(bytesPerLine, length - i);
            byte[] lineBytes = new byte[lineLength];
            buffer.get(lineBytes);

            // 行号
            dump.append(String.format("|%08X| ", i));

            // 十六进制部分
            for (int j = 0; j < bytesPerLine; j++) {
                if (j < lineLength) {
                    hexDump.append(String.format("%02X ", lineBytes[j]));

                    // ASCII部分
                    char c = (char) (lineBytes[j] & 0xFF);
                    asciiDump.append(c >= 32 && c <= 126 ? c : '.');
                } else {
                    hexDump.append("   "); // 填充空格对齐
                    asciiDump.append(' '); // 填充空格对齐
                }
            }

            dump.append(hexDump);
            dump.append("| ");
            dump.append(asciiDump);

            // 对齐最后一行
            if (lineLength < bytesPerLine) {
                for (int j = lineLength; j < bytesPerLine; j++) {
                    dump.append(' ');
                }
            }

            dump.append(" |\n");
        }

        dump.append("+--------+-------------------------------------------------+----------------+");
        return dump.toString();
    }

    public static void main(String[] args) {
        ByteBuffer buffer = ByteBuffer.wrap("Hello!".getBytes());
        prettyPrint(buffer);
    }
}
